#include "resize.h"

namespace sp::Image::Resize{

void registe_resize(){
    resize::registe();
}

resize::resize(std::vector<std::string> v){ // int width, int height
    assert(v.size() == 2);
    name = "resize";
    class_name = "Image-Resize-resize";
    width = std::stoi(v[0]);
    height = std::stoi(v[1]);
    cnt = 0;
    data_type_support.push_back(std::pair<std::vector<uint8_t>, uint8_t>({MAT},MAT));
}

resize::resize(int width, int height){
    name = "resize";
    class_name = "Image-Resize-resize";
    this->width = width;
    this->height = height;
    cnt = 0;
    data_type_support.push_back(std::pair<std::vector<uint8_t>, uint8_t>({MAT},MAT));
}

resize::resize(){
    name = "resize";
    class_name = "Image-Resize-resize";
    cnt = 0;
    data_type_support.push_back(std::pair<std::vector<uint8_t>, uint8_t>({MAT},MAT));
}

resize::~resize(){

}

void resize::registe(){
    Function::Register("Image-Resize-resize", createObject);
    Function::Register("Image-Resize-resize", createObject2);
}

Function* resize::createObject(std::vector<std::string> params){
    return new resize(params);
}

Function* resize::createObject2(){
    return new resize();
}

void resize::start(){

}

bool resize::waitForResource(){
    return true;
}

void resize::process(std::vector<std::vector<Data*>>& data_input, std::vector<Data*>& data_output){
    // 验证输入个数
    assert(batch_size != 0);
    assert(data_input.size() <= batch_size);
    assert(data_input[0].size() == 1);
    // 处理
    for(int i = 0; i < data_input.size(); i++){
        // resize
        if(data_input[i][0] == DATA_END)
            break;
        // 从接收到的data构建cv::Mat src
        Data* d = data_input[i][0];
        cv::Mat* src = new cv::Mat(d->context.mat.rows, d->context.mat.cols, CV_8UC3); 
        src->data = d->context.mat.data;
        src->datastart = d->context.mat.data;
        src->dataend = d->context.mat.data + d->context.mat.rows*d->context.mat.cols*d->context.mat.channels;
        src->datalimit = src->dataend;
        if(DEBUG)
            executor->fout << width << " " << height << std::endl;
        // 从内存池申请data内存，并构建cv::Mat dst
        char* mat_data_ptr = executor->malloc(width, height);
        cv::Mat* dst = new cv::Mat(height, width, CV_8UC3);
        dst->data = (uchar*)mat_data_ptr;
        dst->datastart = dst->data;
        dst->dataend = dst->datastart + height*width*3;
        dst->datalimit = dst->dataend;
        // 进行resize
        cv::resize(*src, *dst, dst->size(), 0, 0, cv::INTER_LINEAR);
        // image write
        // cv::imwrite("./images/resize_" + std::to_string(executor->getId()) + "_" + std::to_string(cnt) + ".png", *dst);
        // 设置Data的值
        char* ptr = executor->malloc(Data_Memory);
        Data* data = new (ptr)Data(d->getAppId(), d->getFlowId(), d->getRequestId(), dst->channels(), dst->rows, dst->cols, dst->data);
        // 释放内存
        if(d->subRefCount() == 0){
            executor->free((char*)(d->context.mat.data));
            executor->free((char*)(d));
        }
        delete src;
        delete dst;
        data_output.push_back(data);
        cnt++;
    }
}

bool resize::releaseResource(){
    return true;
}

void resize::finish(){

}

void resize::copy(Function* other){
    Function::defaultCopy(other);
    resize* oth = dynamic_cast<resize*>(other);
    this->width = oth->width;
    this->height = oth->height;
}

};